package org.xx.armory.xml;

import org.xml.sax.Attributes;

import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.apache.commons.lang3.math.NumberUtils.toInt;
import static org.apache.commons.lang3.math.NumberUtils.toLong;
import static org.xx.armory.commons.Validators.notBlank;
import static org.xx.armory.commons.Validators.notNull;

/**
 * XML文件的属性操作工具类。
 *
 * @author Haart
 */
public final class AttributesHelper {
    private AttributesHelper() {
        throw new UnsupportedOperationException();
    }

    /**
     * 获取指定属性的字符串值。
     *
     * @param attributes
     *         属性集合。
     * @param name
     *         属性的名称。
     * @return 如果属性集合中包含指定的属性则返回该属性的正规化值, 否则返回空字符串。
     * @throws IllegalArgumentException
     *         如果参数{@code attributes}或者{@code name}是{@code null}，或者参数{@code name}只包含空白字符。
     */
    public static String getString(
            Attributes attributes,
            String name
    ) {
        return getString(attributes, name, "");
    }

    /**
     * 获取指定属性的字符串值。
     *
     * @param attributes
     *         属性集合。
     * @param name
     *         属性的名称。
     * @param defaultValue
     *         默认值。
     * @return 如果属性集合中包含指定的属性则返回该属性的正规化值, 否则返回参数{@code defaultValue}。
     * @throws IllegalArgumentException
     *         如果参数{@code attributes}或者参数{@code name}或者参数{@code defaultValue}是{@code null}，或者参数{@code name}只包含空白字符。
     */
    public static String getString(
            Attributes attributes,
            String name,
            String defaultValue
    ) {
        notNull(attributes, "attributes");
        notNull(defaultValue, "defaultValue");

        final String result = attributes.getValue(notBlank(name, "name").trim());
        return result != null ? result : defaultValue;
    }

    /**
     * 获取指定属性的整数值。
     *
     * @param attributes
     *         属性集合。
     * @param name
     *         属性的名称。
     * @param defaultValue
     *         默认值。
     * @return 如果属性集合中包含指定的属性则返回该属性的整数值, 否则返回{@code defaultValue}, 如果该属性的值是{@literal auto}也返回{@code defaultValue}。
     * @throws IllegalArgumentException
     *         如果参数{@code attributes}或者{@code name}是{@code null}，或者参数{@code name}只包含空白字符。
     */
    public static int getInteger(
            Attributes attributes,
            String name,
            int defaultValue
    ) {
        notNull(attributes, "attributes");

        final String s = trimToEmpty(attributes.getValue(notBlank(name, "name").trim())).toLowerCase();

        if ("auto".equals(s)) {
            return defaultValue;
        } else {
            return toInt(s, defaultValue);
        }
    }

    /**
     * 获取指定属性的长整数值。
     *
     * @param attributes
     *         属性集合。
     * @param name
     *         属性的名称。
     * @param defaultValue
     *         属性的缺省值。
     * @return 如果属性集合中包含指定的属性则返回该属性的长整数值, 否则返回{@code defaultValue}, 如果该属性的值是{@literal auto}也返回{@code defaultValue}。
     * @throws IllegalArgumentException
     *         如果参数{@code attributes}或者{@code name}是{@code null}，或者参数{@code name}只包含空白字符。
     */
    public static long getLong(
            Attributes attributes,
            String name,
            long defaultValue
    ) {
        notNull(attributes, "attributes");

        final String s = trimToEmpty(attributes.getValue(notBlank(name, "name").trim())).toLowerCase();

        if ("auto".equals(s)) {
            return defaultValue;
        } else {
            return toLong(s, defaultValue);
        }
    }

    /**
     * 获取指定属性的布尔值。
     *
     * @param attributes
     *         属性集合。
     * @param name
     *         属性的名称。
     * @param defaultValue
     *         默认值。
     * @return 如果属性集合中包含指定的属性则返回该属性的布尔值, 否则返回{@code defaultValue}, 如果该属性的值是{@literal auto}也返回{@code defaultValue}。
     * @throws IllegalArgumentException
     *         如果参数{@code attributes}或者{@code name}是{@code null}，或者参数{@code name}只包含空白字符。
     */
    public static boolean getBoolean(
            Attributes attributes,
            String name,
            boolean defaultValue
    ) {
        notNull(attributes, "attributes");

        final String s = trimToEmpty(attributes.getValue(notBlank(name, "name").trim())).toLowerCase();

        switch (s) {
            case "yes":
            case "1":
            case "true":
            case "on":
            case "t":
            case "y":
                return true;
            case "no":
            case "0":
            case "false":
            case "off":
            case "f":
            case "n":
                return false;
            default:
                return defaultValue;
        }
    }
}
